//============================================================================================
/**
 * @file	bong_sys.c
 * @brief	フィールドでのボングリ成長処理など
 * @author	Nozomu Saito
 * @date	2008.06.04
 */
//============================================================================================

//============================================================================================
//============================================================================================

#include "common.h"
#include "fieldsys.h"

#include "savedata/bong_bed.h"

#include "bong_sys.h"
#include "fieldobj.h"

#include "field_event.h"

#include "itemtool/itemsym.h"

#include "fieldmap_work.h"

static void CreateDummyOBJ(FIELDSYS_WORK *fsys, BONG_SYS_WORK * bsys);
static void DeleteDummyOBJ(BONG_SYS_WORK * bsys);

//============================================================================================
//============================================================================================
//----------------------------------------------------------
//----------------------------------------------------------

//----------------------------------------------------------
//----------------------------------------------------------
struct BONG_SYS_WORK {
	int HeapID;
	NNSG3dRenderObj Render;
	NNSG3dResMdl * Model_p;
	NNSG3dResFileHeader * ResFile;
};

//============================================================================================
//============================================================================================
//----------------------------------------------------------
/**
 * @brief	ボングリ成長制御システムの生成
 * @param	fsys		FIELDSYS_WORKへのポインタ
 * @param	inHeapID	確保するヒープのID
 */
//----------------------------------------------------------
BONG_SYS_WORK * BongSys_Init(FIELDSYS_WORK * fsys, const int inHeapID)
{
	BONG_SYS_WORK * sys;
	sys = sys_AllocMemory(inHeapID, sizeof(BONG_SYS_WORK));
	MI_CpuClear8(sys, sizeof(BONG_SYS_WORK));
	sys->HeapID = inHeapID;
	CreateDummyOBJ(fsys,sys);
	return sys;
}

//----------------------------------------------------------
/**
 * @brief	ボングリ成長制御システムの解放
 * @param	bongsys		BONG_SYS_WORKへのポインタ
 */
//----------------------------------------------------------
void BongSys_Finish(BONG_SYS_WORK * bongsys)
{
	DeleteDummyOBJ(bongsys);
	sys_FreeMemoryEz(bongsys);
}

//----------------------------------------------------------
/**
 * 0時にチェックが入る　ボングリ生成
 * @param	fsys		FIELDSYS_WORKへのポインタ
 */
//----------------------------------------------------------
void BongSys_Growth(FIELDSYS_WORK * fsys)
{
	int i;
	BONG_BED * bbed;
	bbed = SaveData_GetBongBed(fsys->savedata);
	BONGBED_Growth(bbed);
}

//----------------------------------------------------------
/**
 * @brief	ボングリカリングチェック用モデル登録
 * @param	fsys		FIELDSYS_WORKへのポインタ
 * @param	bsys		システムポインタ
 */
//----------------------------------------------------------
static void CreateDummyOBJ(FIELDSYS_WORK *fsys, BONG_SYS_WORK * bsys)
{
	FE_SYS *fes = fsys->fes;
	u32 size = FE_ArcDataSizeGet( fes, NARC_fldeff_kage_nsbmd );	//暫定。影ではなく、ボングリのビルボードにする
	bsys->ResFile = sys_AllocMemory( bsys->HeapID, size );
	FE_ArcDataLoad( fes, NARC_fldeff_kage_nsbmd, bsys->ResFile );
	simple_3DModelSetResFileAlready( &bsys->Render, &bsys->Model_p, &bsys->ResFile );
}

//----------------------------------------------------------
/**
 * @brief	ボングリカリングチェック用モデル解放
 * @param	bsys		システムポインタ
 */
//----------------------------------------------------------
static void DeleteDummyOBJ(BONG_SYS_WORK * bsys)
{
	FE_FreeMemory(bsys->ResFile);
}

//----------------------------------------------------------
/**
 * @brief	視界チェック
 * @param	fsys		FIELDSYS_WORKへのポインタ
 * @param	pos			座標
 *
 * @retval	BOOL		TRUE:視界内
 *
 */
//----------------------------------------------------------
static BOOL CheckInScreen(FIELDSYS_WORK * fsys, const VecFx32 * pos)
{
	const VecFx32 scale = {FX32_ONE, FX32_ONE, FX32_ONE};
	MtxFx33 rot;
	MTX_Identity33(&rot);
	if (BB_CullingCheck3DModel(fsys->fldmap->BongSys->Model_p, pos, &rot, &scale) != 0) {
		return TRUE;
	} else {
		return FALSE;
	}
}

//----------------------------------------------------------
/**
 * @brief	視界チェック
 * @param	fsys		FIELDSYS_WORKへのポインタ
 *
 * 視界に入ったら成長フラグをONにする
 */
//----------------------------------------------------------
void BongSys_CheckInScreen(FIELDSYS_WORK * fsys)
{
	int no = 0;
	FIELD_OBJ_PTR fldobj;
	BONG_BED * bbed = SaveData_GetBongBed(fsys->savedata);
	while (FieldOBJSys_FieldOBJSearch(fsys->fldobjsys, &fldobj, &no, FLDOBJ_STA_BIT_USE) == TRUE) {
		if (FieldOBJ_CheckOBJCodeBonguri(FieldOBJ_OBJCodeGet(fldobj)) == TRUE) {
			if (CheckInScreen(fsys, FieldOBJ_VecPosPtrGet(fldobj))) {
				int id = FieldOBJ_ParamGet(fldobj, FLDOBJ_PARAM_0);
				BONGBED_SetGrowthFlag(bbed, id, TRUE);
			}
		}
	}
}

//============================================================================================
//============================================================================================
//----------------------------------------------------------
/**
 * @brief	ボングリが生っているかどうかのチェック
 * @param	fsys		FIELDSYS_WORKへのポインタ
 * @param	fldobj		ボングリに関連付けられているFIELDOBJへのポインタ
 *
 * @retval	TRUE		ボングリが生っている
 * @retval	FALSE		ボングリが生っていない
 */
//----------------------------------------------------------
BOOL BongSys_IsGrow(FIELDSYS_WORK * fsys, FIELD_OBJ_PTR fldobj)
{
	int code;

	if (fldobj == NULL) {
		return FALSE;
	}

	code = FieldOBJ_OBJCodeGet(fldobj);
	if ( (code != BONGURI01)&&
		 (code != BONGURI02)&&
		 (code != BONGURI03)&&
		 (code != BONGURI04)&&
		 (code != BONGURI05)&&
		 (code != BONGURI06)&&
		 (code != BONGURI07) ){
		return FALSE;
	}

	if (BongSys_GetBongStatus(fsys,fldobj) != BONG_STAT_FRUIT) {
		return FALSE;
	}
	return TRUE;
}

//============================================================================================
//============================================================================================
//----------------------------------------------------------
/**
 * @brief	ボングリを収穫する
 * @param	fsys		FIELDSYS_WORKへのポインタ
 * @param	fldobj		木の実に関連付けられているFIELDOBJへのポインタ
 * @return	BOOL		きのみを取れたかどうか
 */
//----------------------------------------------------------
BOOL BongSys_Take(FIELDSYS_WORK * fsys, FIELD_OBJ_PTR fldobj)
{
	int id, num, type;
	BONG_BED * bbed = SaveData_GetBongBed(fsys->savedata);
	id = FieldOBJ_ParamGet(fldobj, FLDOBJ_PARAM_0);

	OS_Printf("FLDOBJPARAM0＿GET %d \n",id);

	BONGBED_GetHarvest(bbed, id);
	return TRUE;
}

//-------------------------------------------------------------------------
/**
 * @brief	ボングリの状態を取得する
 * @param	fsys		FIELDSYS_WORKへのポインタ
 * @param	fldobj		ボングリに関連付けられているFIELDOBJへのポインタ
 * @return	BONGSTAT	ボングリの状態
 */
//-------------------------------------------------------------------------
BONG_STAT BongSys_GetBongStatus(const FIELDSYS_WORK * fsys, CONST_FIELD_OBJ_PTR fldobj)
{
	int id;
	BONG_BED * bbed = SaveData_GetBongBed(fsys->savedata);
	id = FieldOBJ_ParamGet(fldobj, FLDOBJ_PARAM_0);
	return BONGBED_GetBongStatus(bbed, id);
}

//-------------------------------------------------------------------------
/**
 * @brief	ボングリの種類を取得する
 * @param	fsys		FIELDSYS_WORKへのポインタ
 * @param	fldobj		ボングリに関連付けられているFIELDOBJへのポインタ
 * @return	u16			ボングリの種類
 */
//-------------------------------------------------------------------------
int BongSys_GetBongType(const FIELDSYS_WORK * fsys, CONST_FIELD_OBJ_PTR fldobj)
{
	int id;
	BONG_BED * bbed = SaveData_GetBongBed(fsys->savedata);
	id = FieldOBJ_ParamGet(fldobj, FLDOBJ_PARAM_0);
	return BONGBED_GetBongType(bbed, id);
}

//-------------------------------------------------------------------------
/**
 * @brief	ボングリのカラーIDを取得する
 * @param	fsys		FIELDSYS_WORKへのポインタ
 * @param	fldobj		ボングリに関連付けられているFIELDOBJへのポインタ
 * @return	int			ボングリのカラーID
 */
//-------------------------------------------------------------------------
int BongSys_GetBongColor(const FIELDSYS_WORK * fsys, CONST_FIELD_OBJ_PTR fldobj)
{
	int id;
	BONG_BED * bbed = SaveData_GetBongBed(fsys->savedata);
	id = FieldOBJ_ParamGet(fldobj, FLDOBJ_PARAM_0);
	return BONGBED_GetBongColor(bbed, id);
}

//-------------------------------------------------------------------------
/**
 * @brief	ボングリのアイテムナンバーを取得
 * @param	fsys		FIELDSYS_WORKへのポインタ
 * @param	fldobj		ボングリに関連付けられているFIELDOBJへのポインタ
 * @return	u16			ボングリのアイテムナンバー
 */
//-------------------------------------------------------------------------
int BongSys_GetBongItemNo(const FIELDSYS_WORK * fsys, CONST_FIELD_OBJ_PTR fldobj)
{
	int item_no;
	int id;
	int bong_type;
	BONG_BED * bbed = SaveData_GetBongBed(fsys->savedata);
	id = FieldOBJ_ParamGet(fldobj, FLDOBJ_PARAM_0);
	bong_type = BONGBED_GetBongType(bbed, id);
	if (bong_type == 0){
		GF_ASSERT(0);
		bong_type = 1;
	}else {
		bong_type-=1;
	}

	item_no = ITEM_AOBONGURI + bong_type;

	return item_no;
}
